package com.opengw.configuration.config;

//~--- non-JDK imports --------------------------------------------------------

import com.opengw.configuration.entity.ConfigUser;
import com.opengw.configuration.entity.ConfigGroup;
import com.opengw.configuration.support.Base64;
import com.opengw.exception.OpenGWException;
import com.opengw.http.HTTPConstants;
import com.opengw.http.HTTPRequest;
import com.opengw.http.HTTPResponse;

//~--- JDK imports ------------------------------------------------------------

import java.util.HashMap;
import java.util.StringTokenizer;

import javax.persistence.Entity;
import javax.persistence.Transient;

/**
 * Class description
 *
 *
 * @version        
 * @author         ismozen    
 */
@Entity
public class BasicAuthentication extends RouteConfig {

    /** Field description */
    private String password;

    /** Field description */
    private ConfigUser user;

    /** Field description */
    private ConfigGroup userGroup;

    /** Field description */
    private String username;
    
    public BasicAuthentication(){
    	super();
    }

    /**
     * Constructs BasicAuthentication
     * if before request is true it need username and password for requests
     * if before request is false it set username and password before route request
     *
     * @param beforeRequest
     */
    public BasicAuthentication(boolean beforeRequest) {
        super(!beforeRequest, beforeRequest, false, false);
        configText = "****************deneme****************";
    }

    /**
     * Method description
     *
     *
     * @param request
     *
     * @throws OpenGWException
     */
    @Override
    public void doChangeRequest(HTTPRequest request) throws OpenGWException {
        String authHeader   = "Basic ";
        Base64 base64       = new Base64();
        String encodedToken = base64.encode((this.username + ":" + this.password).getBytes());

        authHeader += encodedToken;
        request.setRequestHeader(HTTPConstants.AUTHORIZATION_HEADER, authHeader);
    }

    /**
     * Method description
     *
     *
     * @param response
     *
     * @throws OpenGWException
     */
    @Override
    public void doChangeResponse(HTTPResponse response) throws OpenGWException {}

    /**
     * Method description
     *
     *
     * @param request
     *
     * @throws OpenGWException
     */
    @Override
    public void doControlRequest(HTTPRequest request) throws OpenGWException {
        String  authHeader = request.getRequestHeader(HTTPConstants.AUTHORIZATION_HEADER);
        String  username   = null;
        String  password   = null;
        boolean verified   = false;

        if (authHeader != null) {
            StringTokenizer st = new StringTokenizer(authHeader);

            if (st.hasMoreTokens()) {
                String basic = st.nextToken();

                if (basic.equalsIgnoreCase("Basic")) {
                    String credentials = st.nextToken();

                    // TODO change here use own base64 package or diff
                    Base64 base64   = new Base64();
                    String userPass = new String(base64.decode(credentials));
                    int    p        = userPass.indexOf(":");

                    if (p != -1) {
                        username = userPass.substring(0, p);
                        password = userPass.substring(p + 1);

                        // TODO SHA1 olarak tutulacak şifreler
                        if (this.user != null) {
                            if ((username.trim().equals(this.user.getUsername()))
                                    && (password.trim().equals(this.user.getPassword()))) {
                                verified = true;
                            }
                        }

                        if (this.userGroup != null) {
                            verified = this.userGroup.controlUser(username, password);
                        }
                    }
                }
            }
        }

        if (!verified) {
            HashMap<String, String> responseHeaders = new HashMap<String, String>();

            responseHeaders.put("WWW-Authenticate",
                                "Basic realm=\"Login RDM\n You must enter valid password to enter this resource\"");

            HTTPResponse response = new HTTPResponse(responseHeaders, null);

            response.setResponseCode(401);

            throw new OpenGWException(OpenGWException.AUTHENTICATION_FAILED, response);
        }

        request.removeRequestHeader(HTTPConstants.AUTHORIZATION_HEADER);
    }

    /**
     * Method description
     *
     *
     * @param response
     *
     * @throws OpenGWException
     */
    @Override
    public void doControlResponse(HTTPResponse response) throws OpenGWException {}

    /**
     * Method description
     *
     *
     * @param userGroup
     */
    public void setUserGroup(ConfigGroup userGroup) {
        this.userGroup = userGroup;
    }

    /**
     * Method description
     *
     *
     * @return
     */
	@Transient
    public ConfigGroup getUserGroup() {
        return userGroup;
    }

    /**
     * Method description
     *
     *
     * @param user
     */
    public void setUser(ConfigUser user) {
        this.user = user;
    }

    /**
     * Method description
     *
     *
     * @return
     */
	@Transient
    public ConfigUser getUser() {
        return user;
    }

    /**
     * Method description
     *
     *
     * @param username
     */
    public void setUsername(String username) {
        this.username = username;
    }

    /**
     * Method description
     *
     *
     * @return
     */
	@Transient
    public String getUsername() {
        return username;
    }

    /**
     * Method description
     *
     *
     * @param password
     */
    public void setPassword(String password) {
        this.password = password;
    }

    /**
     * Method description
     *
     *
     * @return
     */
	@Transient
    public String getPassword() {
        return password;
    }
}


//~ Formatted by Jindent --- http://www.jindent.com
